﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SharpSphinx.Linguist.Acoustic
{
    public class LeftRightContext : Context 
    {
        String stringRepresention;
        Unit[] leftContext;
        Unit[] rightContext;
        private static bool CACHING_CONTEXTS = true; 
        private static Dictionary<String, LeftRightContext> cache;
        
        public static void StaticInit()
        {
            if (CACHING_CONTEXTS)
            {
                cache = new Dictionary<string, LeftRightContext>();
            }
        }
            
       

        private LeftRightContext(Unit[] leftContext,Unit[] rightContext)
        {
            this.leftContext = leftContext;
            this.rightContext = rightContext;

        }


        public override string ToString()
        {
            if (stringRepresention == null)
            {
               /*  stringRepresention = */
            }

            return stringRepresention;
        }
 
        public static LeftRightContext Get(Unit[] leftContext, Unit[] rightContext)
        {
            LeftRightContext context;

            if (CACHING_CONTEXTS)
            {
                String name = getStringRepresentation(leftContext, rightContext);

                cache.TryGetValue(name, out context);

                if (context == null)
                {
                    context = new LeftRightContext(leftContext, rightContext);
                    cache.Add(name, context);
                }
            }
            else
            {
                context = new LeftRightContext(leftContext, rightContext);
            }
            return context;
        }

        private static String getStringRepresentation(Unit[] leftContext,Unit[] rightContext) {
            return getContextName(leftContext) + ',' + getContextName(rightContext);
        }

        public Unit[] getLeftContext()
        {
            return leftContext;
        }

        public Unit[] getRightContext()
        {
            return rightContext;
        }

        public static String getContextName(Unit[] context)
        {
            if (context == null)
                return "*";
            if (context.Length == 0)
                return "(Empty)";
            StringBuilder sb = new StringBuilder(); 
           foreach (Unit unit in context)
            {
                sb.Append(unit == null ? null : unit.Name).Append('.'); 

            }
           sb.Length =  (sb.Length - 1);
           return sb.ToString();
        }

        public override bool IsPartialMatch(Context context)
        {
            if (context is LeftRightContext)
            {
                LeftRightContext lrContext = (LeftRightContext)context;
                Unit[] lc = lrContext.getLeftContext();
                Unit[] rc = lrContext.getRightContext();

                return (lc == null || leftContext == null || Unit.IsContextMatch(lc, leftContext))
                    && (rc == null || rightContext == null || Unit.IsContextMatch(rc, rightContext)); 

            }
            return context == Context.Empty_Context && leftContext == null && rightContext == null;
        }
    }
}
